home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Programmer Disk
/
The Programmer Disk (Microforum).iso
/
xpro
/
c
/
pro19
/
csyslib.c
< prev
next >
Wrap
Text File
|
1987-10-04
|
8KB
|
373 lines
/*
** CSYSLIB -- System-Level Library Functions
** Modified for MS-DOS 2 by R. Grehan
*/
#include stdio.h
#include clib.def
#define NOCCARGC /* no argument count passing */
#define DIR /* compile directory option */
/*
****************** System Variables ********************
*/
int
errno, /* Error number holding var */
Ucnt=1, /* arg count for main */
Uvec[20], /* arg vectors for main */
Ustatus[MAXFILES] = {RDBIT, WRTBIT, RDBIT|WRTBIT},
/* status of respective file */
Udevice[MAXFILES] = {CONSOL, CONSOL, CONSOL},
/* non-disk device assignments */
Unextc[MAXFILES] = {EOF, EOF, EOF},
/* pigeonhole for ungetc bytes */
Ufd[MAXFILES] = {0, 1, 2};
/* Map logical fd's to physical */
char
*Umemptr, /* pointer to free memory. */
Uarg1[]="*"; /* first arg for main */
/*
*************** System-Level Functions *****************
*/
/*
** -- Process Command Line, Execute main(), and Exit to CP/M
*/
Umain() {
Uparse();
main(Ucnt,Uvec);
exit(0);
}
/*
** Parse command line and setup argc and argv.
*/
Uparse() {
char *count, *ptr;
count = 128; /* Reserve bytes */
ptr = Ualloc(count+1, YES);
count=Ugcmdtl(ptr); /* Get command tail - null pad */
Uvec[0]=Uarg1; /* first arg = "*" */
while (*ptr) {
if(isspace(*ptr)) {++ptr; continue;}
switch(*ptr) {
case '<': ptr = Uredirect(ptr, "r", stdin);
continue;
case '>': if(*(ptr+1) == '>')
ptr = Uredirect(ptr+1, "a", stdout);
else ptr = Uredirect(ptr, "w", stdout);
continue;
default: if(Ucnt < 20) Uvec[Ucnt++] = ptr;
ptr = Ufield(ptr);
}
}
}
Ugcmdtl(mypt) char *mypt; {
#asm
MOV AH,62H ;Get program segment prefix
INT 21H
MOV AX,DS ;Get our segment
MOV ES,AX ;Will be destination
MOV DS,BX ;PSP segment is source
MOV SI,80H ;Offset to command tail byte count
MOV CL,[SI] ;Get byte count
MOV BX,CX ;Save for return
INC SI ;Bump pointer
POP AX ;Return address
POP DI ;mypt
PUSH DI ;Restore
PUSH AX
CLD ;Set direction
REP MOVSB ;Move it in
MOV BYTE PTR ES:[DI],0 ;Move in Null
MOV AX,ES ;Restore our segment
MOV DS,AX
XOR CX,CX ;Zero in CX
#endasm
}
/*
** Isolate next command-line field.
*/
Ufield(ptr) char *ptr; {
while(*ptr) {
if(isspace(*ptr)) {
*ptr = NULL;
return (++ptr);
}
++ptr;
}
return (ptr);
}
/*
** Redirect stdin or stdout.
*/
Uredirect(ptr, mode, std) char *ptr, *mode; int std; {
char *fn;
fn = ++ptr;
ptr = Ufield(ptr);
if(Uopen(fn, mode, std)==ERR) exit('R');
return (ptr);
}
/*
** ------------ File Open
*/
/*
** Open file on specified fd.
*/
Uopen(fn, mode, fd) char *fn, *mode; int fd; {
int pfd;
if(!strchr("rwau", *mode)) return (ERR);
Unextc[fd] = EOF;
if(strcmp(fn,"CON:")==0) {
Udevice[fd]=CONSOL; Ustatus[fd]=RDBIT|WRTBIT; return (fd);
}
if(strcmp(fn,"LST:")==0) {
Udevice[fd]=PRINTR; Ustatus[fd]=WRTBIT; return (fd);
}
Udevice[fd] = 0;
switch(*mode) {
case 'r': {
if((pfd=Umsdos(fn,0,0,OPNFIL+RACCESS))==ERR) return (ERR);
Ustatus[fd] = RDBIT;
Ufd[fd]=pfd;
break;
}
case 'u': {
if((pfd=Umsdos(fn,0,0,OPNFIL+RWACCESS))==ERR)
return (ERR);
Ustatus[fd] = RDBIT|WRTBIT;
Ufd[fd]=pfd;
break;
}
case 'w': {
if((pfd=Umsdos(fn,0,0,OPNFIL+WACCESS))!=ERR) {
Umsdos(0,0,pfd,CLOFIL);
Umsdos(fn,0,0,DELFIL); }
create:
if((pfd=Umsdos(fn,0,0,MAKFIL))==ERR) return (ERR);
Ustatus[fd] = EOFBIT|WRTBIT;
Ufd[fd]=pfd;
break;
}
default: { /* append mode */
if((pfd=Umsdos(fn,0,0,OPNFIL+RWACCESS))==ERR)
goto create;
Ustatus[fd] = RDBIT;
Ufd[fd]=pfd;
seek(fd, -1, -1, 2);
while(fgetc(fd)!=EOF) ;
Ustatus[fd] = EOFBIT|WRTBIT;
}
}
return (fd);
}
/*
** ------------ File Input
*/
/*
** Binary-stream input fd.
*/
Uread(buff,fd,n) int fd; char *buff, *n; {
char *i; /* Fake unsigned */
char ch;
i=n;
switch (Umode(fd)) {
default: Useterr(fd); return (EOF);
case RDBIT:
case RDBIT|WRTBIT:
}
if(Unextc[fd] != EOF) {
*buff++=Unextc[fd];
Unextc[fd] = EOF;
if((--n)==0) return(1) ;
}
switch(Udevice[fd]) {
/* PUN & LST can't occur since they are write mode */
case CONSOL: while(n--) {
if((ch=Uconin())==FILEOF) return(EOF);
*buff++=ch;
} return(i-n);
default:
if((i=Umsdos(buff,n,Ufd[fd],RDFIL))==ERR)
return(ERR);
if(i==0) Useteof(fd);
return(i);
}
}
/*
** Console character input.
*/
Uconin() {
int ch;
while(!(ch = Dcio(255))) ;
switch(ch) {
case ABORT: exit(0);
case LF:
case CR: Uconout(LF); return (Uconout(CR));
case DEL: ch = RUB;
default: if(ch < 32) { Uconout('^'); Uconout(ch+64);}
else Uconout(ch);
return (ch);
}
}
/*
** Special direct keyboard input for MS-DOS
*/
Dcio(ch) int ch; {
#asm
POP SI
POP DX
PUSH DX
PUSH SI
MOV AH,6 ;Direct I/O
INT 21H
JNZ Dcio1
XOR AL,AL ;No char.
Dcio1:
MOV BL,AL
XOR BH,BH
#endasm
}
/*
** ------------ File Output
*/
/*
** Binary-Stream output to fd.
*/
Uwrite(buff, fd, n) int fd; char *buff, *n; {
char *i;
i=n;
switch (Umode(fd)) {
default: Useterr(fd); return (EOF);
case WRTBIT:
case WRTBIT|RDBIT:
case WRTBIT|EOFBIT:
case WRTBIT|EOFBIT|RDBIT:
}
switch(Udevice[fd]) {
/* RDR can't occur since it is read mode */
case CONSOL: while (n--) {
Dcio(*buff++);
} return(i-n);
case PRINTR: while (n--) {
Umsdos(*buff++,0,0,PRTOUT);
} return (i-n);
default:
return(Umsdos(buff,n,Ufd[fd],WRFIL));
}
}
/*
** Console character output.
*/
Uconout(ch) int ch; {
Dcio(ch);
return (ch);
}
/*
** ------------ Buffer Service
*/
/*
** Return fd's open mode, else NULL.
*/
Umode(fd) char *fd; {
if(fd < MAXFILES) return (Ustatus[fd]);
return (NULL);
}
/*
** Set eof status for fd and
** disable future i/o unless writing is allowed.
*/
Useteof(fd) int fd; {
Ustatus[fd] |= EOFBIT;
}
/*
** Clear eof status for fd.
*/
Uclreof(fd) int fd; {
Ustatus[fd] &= ~EOFBIT;
}
/*
** Set error status for fd.
*/
Useterr(fd) int fd; {
Ustatus[fd] |= ERRBIT;
}
/*
** ------------ Memory Allocation
*/
/*
** Allocate n bytes of (possibly zeroed) memory.
** Entry: n = Size of the items in bytes.
** clear = "true" if clearing is desired.
** Returns the address of the allocated block of memory
** or NULL if the requested amount of space is not available.
*/
Ualloc(n, clear) char *n; int clear; {
char *oldptr;
if(n < avail(YES)) {
if(clear) pad(Umemptr, NULL, n);
oldptr = Umemptr;
Umemptr += n;
return (oldptr);
}
return (NULL);
}
/* MS-DOS interface
** If there's an error code, we store it in errno and
** return ERR
*/
Umsdos(dx,cx,bx,ax) int dx,cx,bx,ax; {
#asm
POP SI ;Return address
POP AX ;Load all the registers
POP BX
POP CX
POP DX
PUSH DX ;Now restore them
PUSH CX
PUSH BX
PUSH AX
PUSH SI
INT 21H ;Issue the call do DOS
JNC UMSDOS1 ;Jump if no error
MOV _ERRNO,AX
MOV AX,-2 ;ERR
UMSDOS1:
MOV BX,AX
XOR CX,CX ;Zero in CX
#endasm
}